package com.xuelang.pipeline.artifact.infrastructure.resource.repository;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xuelang.pipeline.artifact.client.common.constant.Constant;
import com.xuelang.pipeline.artifact.client.common.result.PageRecord;
import com.xuelang.pipeline.artifact.client.resource.dto.ArtifactToolQuery;
import com.xuelang.pipeline.artifact.domain.resource.ArtifactTool;
import com.xuelang.pipeline.artifact.domain.resource.repository.ArtifactToolRepository;
import com.xuelang.pipeline.artifact.infrastructure.resource.converter.ArtifactToolToArtifactToolDOConverter;
import com.xuelang.pipeline.artifact.infrastructure.resource.dataobject.ArtifactAttributeDO;
import com.xuelang.pipeline.artifact.infrastructure.resource.dataobject.ArtifactToolDO;
import com.xuelang.pipeline.artifact.infrastructure.resource.mapper.ArtifactToolMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * 制品工具仓库实现类
 *
 * @author xiwen.zxg
 * @since 2024/5/15
 */
@Slf4j
@Repository
public class ArtifactToolRepositoryImpl implements ArtifactToolRepository {

    @Autowired
    ArtifactToolMapper artifactToolMapper;

    @Override
    public PageRecord<ArtifactTool> pageList(long currentPage, long pageSize, ArtifactToolQuery artifactToolQuery) {
        currentPage = currentPage < 1 ? 1 : currentPage;
        pageSize = pageSize < 1 ? 10 : pageSize;
        Page<ArtifactTool> page = new Page<>(currentPage, pageSize);
        MPJLambdaWrapper<ArtifactToolDO> wrapper = new MPJLambdaWrapper<ArtifactToolDO>();
        wrapper.selectAll(ArtifactToolDO.class)
                .eq(ArtifactToolDO::getDataSource, StrUtil.isNotBlank(artifactToolQuery.getDataSource()) ? artifactToolQuery.getDataSource() : Constant.DEFAULT_DB_NOT_EXISTS_DATA);
        wrapper.eq(StrUtil.isNotBlank(artifactToolQuery.getArtifactType()), ArtifactToolDO::getArtifactType, artifactToolQuery.getArtifactType());
        wrapper.and(StrUtil.isNotBlank(artifactToolQuery.getCondition()), wp -> wp
                        .like(ArtifactToolDO::getArtifactName, artifactToolQuery.getCondition())
                        //.or().like(ArtifactToolDO::getArtifactCode, artifactToolQuery.getCondition())
                        //.or().like(ArtifactToolDO::getDescription, artifactToolQuery.getCondition())
                )
                .apply(StrUtil.isNotBlank(artifactToolQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')>={0}", artifactToolQuery.getStartDate())
                .apply(StrUtil.isNotBlank(artifactToolQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')<={0}", artifactToolQuery.getEndDate())
                .orderByDesc(ArtifactAttributeDO::getCreateTime);
        artifactToolMapper.selectJoinPage(page, ArtifactTool.class, wrapper);
        return new PageRecord<>(
                page.getCurrent(),
                page.getSize(),
                page.getTotal(),
                page.getPages(),
                page.getRecords()
        );
    }

    @Override
    public List<ArtifactTool> list(ArtifactToolQuery artifactToolQuery) {
        MPJLambdaWrapper<ArtifactToolDO> wrapper = new MPJLambdaWrapper<ArtifactToolDO>();
        wrapper.selectAll(ArtifactToolDO.class)
                .eq(ArtifactToolDO::getDataSource, StrUtil.isNotBlank(artifactToolQuery.getDataSource()) ? artifactToolQuery.getDataSource() : Constant.DEFAULT_DB_NOT_EXISTS_DATA);
        wrapper.eq(StrUtil.isNotBlank(artifactToolQuery.getArtifactType()), ArtifactToolDO::getArtifactType, artifactToolQuery.getArtifactType());
        wrapper.and(StrUtil.isNotBlank(artifactToolQuery.getCondition()), wp -> wp
                                .like(ArtifactToolDO::getArtifactName, artifactToolQuery.getCondition())
                        //.or().like(ArtifactToolDO::getArtifactCode, artifactToolQuery.getCondition())
                        //.or().like(ArtifactToolDO::getDescription, artifactToolQuery.getCondition())
                )
                .apply(StrUtil.isNotBlank(artifactToolQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')>={0}", artifactToolQuery.getStartDate())
                .apply(StrUtil.isNotBlank(artifactToolQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')<={0}", artifactToolQuery.getEndDate())
                .orderByDesc(ArtifactAttributeDO::getCreateTime);
        return artifactToolMapper.selectJoinList(ArtifactTool.class, wrapper);
    }


    @Override
    public Boolean save(ArtifactTool artifactTool) {
        return artifactToolMapper.insert(ArtifactToolToArtifactToolDOConverter.INSTANCE.artifactToolToArtifactToolDO(artifactTool)) == 1;
    }

    @Override
    public Boolean update(ArtifactTool artifactTool) {
        return artifactToolMapper.update(
                ArtifactToolToArtifactToolDOConverter.INSTANCE.artifactToolToArtifactToolDO(artifactTool),
                Wrappers.lambdaQuery(ArtifactToolDO.class).eq(ArtifactToolDO::getUuid, artifactTool.getUuid())) == 1;
    }

    @Override
    public Boolean delete(String artifactToolUuid) {
        return artifactToolMapper.delete(Wrappers.lambdaQuery(ArtifactToolDO.class)
                .eq(ArtifactToolDO::getUuid, artifactToolUuid)) == 1;
    }

    @Override
    public ArtifactTool query(String artifactToolUuid) {
        ArtifactToolDO artifactToolDO = artifactToolMapper.selectOne(Wrappers.lambdaQuery(ArtifactToolDO.class).eq(ArtifactToolDO::getUuid, artifactToolUuid));
        return ArtifactToolToArtifactToolDOConverter.INSTANCE.artifactToolDOToArtifactTool(artifactToolDO);
    }

    @Override
    public Boolean existsArtifactCodeAndNameByProjectCode(String uuid, String projectCode, String artifactCode, String artifactName) {
        List<ArtifactToolDO> artifactToolDOS = artifactToolMapper.selectList(Wrappers.lambdaQuery(ArtifactToolDO.class).eq(ArtifactToolDO::getProjectCode, projectCode));
        if (ObjectUtil.isEmpty(artifactToolDOS)) {
            return false;
        }
        return artifactToolDOS.stream().anyMatch(artifactToolDO ->
                (StrUtil.equals(artifactName, artifactToolDO.getArtifactName()) || StrUtil.equals(artifactCode, artifactToolDO.getArtifactCode()))
                        && !ObjectUtil.equals(uuid, artifactToolDO.getUuid())
        );
    }

    @Override
    public ArtifactTool getArtifactToolByInstanceRepositoryName(String repositoryName) {
        MPJLambdaWrapper<ArtifactToolDO> wrapper = new MPJLambdaWrapper<ArtifactToolDO>();
        wrapper.select(ArtifactToolDO::getUuid, ArtifactToolDO::getInstanceRepositoryName, ArtifactToolDO::getArtifactType)
                .eq(ArtifactToolDO::getInstanceRepositoryName, repositoryName);
        return artifactToolMapper.selectJoinOne(ArtifactTool.class, wrapper);
    }

    @Override
    public List<ArtifactTool> listArtifactTool() {
        return artifactToolMapper.selectJoinList(ArtifactTool.class, null);
    }

}
